<template>
  <div>
    <base-right-dialog
      ref="baseRightDialog"
      :footerShow="true"
      :appendBody="true"
      :dialogVisible.sync="drawer"
      title="权限分配"
      @handleClose="handleDialogClose"
      @handleConfirmClick="handleConfirmClick"
      :size="'820px'"
    >
      <el-table
        border
        ref="multipleTable"
        :data="menuDatas"
        row-key="id"
        tooltip-effect="dark"
        style="width: 100%"
        :default-expand-all="true"
        :default-checked-keys="keys"
        @select-all="selectAll"
        @select="handleSelectionChange"
        v-loading="buttonLoading"
      >
        <el-table-column
          type="selection"
          width="45"
          :reserve-selection="true"
        ></el-table-column>
        <el-table-column prop="label" label="菜单名称"></el-table-column>
      </el-table>
    </base-right-dialog>
  </div>
</template>

<script>
import router from "@/router";
import baseRightDialog from "@/components/base/baseRightDialog";
import { authApi } from "@/api/apis/auth";
export default {
  data() {
    return {
      menuDatas: [],
      drawer: false,
      multipleSelection: [],
      keys: [],
      isAllSelect: false,
      selected: false,
      childNode: false,
      build: "",
      activeName: "first",
      buttonLoading: false,
    };
  },

  components: {
    baseRightDialog,
  },
  methods: {
    openDialog(type, row, el, id) {
      if (el == false) {
        this.$vmNews("请点击左侧选择角色", "warning");
      } else {
        this.drawer = true;
        this.rolesId = id;
        this.init(row);
      }
    },
    async init(row) {
      this.loading = true;
      let params = {};
      let res = await authApi(
        "moduleService",
        "module",
        "queryTree",
        "",
        params
      );
      this.loading = false;
      if (res.status == "200") {
        this.menuDatas = res.attribute;
        this.$nextTick(() => {
          this.exhibitList(row);
        });
      }
    },
    // 默认选中
    exhibitList(id) {
      let data = this.treeToArray(this.menuDatas);
      data.forEach((el, index) => {
        if (id.includes(el.id)) {
          this.$refs.multipleTable.toggleRowSelection(el, true);
        }
      });
    },
    // 全选/取消全选
    selectAll() {
      let data = this.treeToArray(this.menuDatas);
      this.selected = !this.selected;
      data.forEach((el, index) => {
        this.$refs.multipleTable.toggleRowSelection(el, this.selected);
      });
    },
    handleSelectionChange(val, row) {
      this.multipleSelection = val;
      let data = this.treeToArray([row]);
      this.childNode = !this.childNode;
      if (data.length > 1) {
        data.forEach((el, index) => {
          this.$refs.multipleTable.toggleRowSelection(el, this.childNode);
        });
        let ids = data[0].id;
        let arr = this.treeFindPath(
          this.menuDatas,
          (data) => data.id == ids,
          "id"
        );
        arr = arr.splice(0, arr.length - 1);
        let dataList = [];
        let allList = this.treeToArray(this.menuDatas);
        allList.forEach((el, index) => {
          if (arr.includes(el.id)) {
            dataList.push(el);
          }
        });
        dataList.forEach((el, index) => {
          this.$refs.multipleTable.toggleRowSelection(el, true);
        });
      } else {
        let ids = data[0].id;
        let arr = this.treeFindPath(
          this.menuDatas,
          (data) => data.id == ids,
          "id"
        );
        arr = arr.splice(0, arr.length - 1);
        let dataList = [];
        let allList = this.treeToArray(this.menuDatas);
        allList.forEach((el, index) => {
          if (arr.includes(el.id)) {
            dataList.push(el);
          }
        });
        dataList.forEach((el, index) => {
          this.$refs.multipleTable.toggleRowSelection(el, true);
        });
      }
    },
    // 数据扁平
    treeToArray(items) {
      let children = [];
      items.forEach((item) => {
        children.push(item);
        if (item.children) {
          children = children.concat(this.treeToArray(item.children));
        }
      });
      return children;
    },
    handleDialogClose() {
      let data = this.treeToArray(this.menuDatas);
      data.forEach((el, index) => {
        this.$refs.multipleTable.toggleRowSelection(el, false);
      });
      this.changeMenu(this.menuDatas, 0);
      this.drawer = false;
    },
    async handleConfirmClick() {
      let data = {
        id: this.rolesId,
      };
      data.modulesIds = Object.assign([], []);
      this.$refs.multipleTable.selection.forEach((el, index) => {
        data.modulesIds.push(el.id);
      });
      const res = await authApi(
        "roleService",
        "role",
        "addOrUpdateRoleModule",
        "",
        data
      );
      if (res.status == "200") {
        this.handleDialogClose();
        this.$vmNews("添加成功", "success");
        this.$emit("userUnderRole");
        this.changeSystemMenu()
      }
    },
    changeSystemMenu() {

      this.$store.dispatch("GenerateRoutes").then((accessRoutes) => {
        // 根据roles权限生成可访问的路由表
        for (let i = 0, length = accessRoutes.length; i < length; i += 1) {
          const element = accessRoutes[i];
          router.addRoutes(accessRoutes); // 动态添加可访问路由表
        }
        localStorage.setItem("routeList", JSON.stringify(accessRoutes));
      });
    },
    changeMenu(data, num) {
      let level = num;
      level = level + 1;
      data.forEach((el) => {
        el.buttonList = [];
        el.type = false;
        if (el.children != null && el.children && el.children.length) {
          this.changeMenu(el.children, level);
        }
      });
    },
    treeFindPath(tree, func, field = "", path = []) {
      if (!tree) return [];
      for (const data of tree) {
        field === "" ? path.push(data) : path.push(data[field]);
        if (func(data)) return path;
        if (data.children) {
          const findChildren = this.treeFindPath(
            data.children,
            func,
            field,
            path
          );
          if (findChildren.length) return findChildren;
        }
        path.pop();
      }
      return [];
    },
  },
};
</script>
<style scoped lang="scss">
.rightDialog {
  height: 100%;
  padding: 0 16px;
}
::v-deep .cell {
  display: flex;
}
::v-deep .el-checkbox-group {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}
::v-deep .el-checkbox {
  margin-right: 15px;
}
::v-deep .el-tabs__nav {
  transform: translateX(22px) !important;
}
</style>
